#include "FKFileSender.h"

#include <QFile>
#include <QDir>
#include <QFileInfo>

#include "FKLogger.h"

QMap<QString,QString> FKFileSender::_fileMap;
QMap<QString,QFile*> FKFileSender::_opened;
QMap<QString,int> FKFileSender::_streamers;

FKFileSender::FKFileSender(QObject *parent):FKFileManager(parent){
    FK_CBEGIN
    FK_CEND
}

FKFileSender::~FKFileSender(){
    FK_DBEGIN
    foreach(QString file,_lastBlockPosition.keys())endFile(file);
    FK_DEND
}

void FKFileSender::getNextBlock(QVariant vfile){
    QString file(vfile.toString());
    if(_opened.contains(file)){
        emit reply(nextBlock(file));
    }else{
        if(_fileMap.contains(file)){
            emit reply(newFile(file));
        }else{
            emit reply(error(file, QString(tr("Cannot find file"))));
        }
    }
}

QVariant FKFileSender::nextBlock(QString file){
//    FK_MLOG("next block DL")
    QFile* f=_opened[file];
    if(f->isReadable()){
        qint64 pos=_lastBlockPosition.value(file,-1);
        if(pos==-1){
            return newFile(file);
        }else{
            if(pos<f->size()){
                f->seek(pos);
                _lastBlockPosition[file]=pos+blockSize;
                return packVar(nextOne,file,QVariant(f->read(blockSize)));
            }else{
                return endFile(file);
            }
        }
    }else{
        return error(file,QString(tr("Cannot access file")));
    }
}

QVariant FKFileSender::newFile(QString file){
//    FK_MLOG("new file DL")
    QFile* f=_opened.value(file,0);
    if(!f){
        f=new QFile(QFileInfo(QDir(_rootPath),_fileMap[file]).absoluteFilePath());
        FK_MLOGV("opening",f->fileName())
        if(!f->open(QIODevice::ReadOnly))return error(file,QString(tr("Cannot open file")));
        _opened[file]=f;
        _lastBlockPosition[file]=0;
    }
    _streamers[file]=_streamers.value(file,0)+1;
    return packVar(newOne,file,QVariant(_fileMap[file]));
}

QVariant FKFileSender::endFile(QString file){
//    FK_MLOG("end file DL")
    _lastBlockPosition.remove(file);
    _streamers[file]=_streamers[file]-1;
    if(!_streamers[file]){
        QFile* f=_opened.take(file);
        f->close();
        f->deleteLater();
    }
    return packVar(lastOne,file,QVariant());
}

QVariant FKFileSender::error(QString file, QString message){
//    FK_MLOG("error DL")
    return packVar(errorOne,file,QVariant(message));
}

void FKFileSender::setFileMap(QMap<QString,QString> fileMap){
    _fileMap=fileMap;
}

void FKFileSender::interruptUploading(QString file){
    endFile(file);
}
